<template>
    <!-- <input type="number" name="" id="" :value="prop.conf.val.norm" @change="e => {
        prop.conf.valChange(e.target.value)
    }" :max="prop.conf.val.max"  :min="prop.conf.val.min"> -->

    <!-- 滑动条 -->
    <div class="block" :style="`margin-top: ${prop.conf.mt ?? 0};`">
        <div class="desc-bar">
            <span class="name">{{ prop.conf.fn }}</span>
            <span class="desc" v-if="prop.conf.desc">
                <span v-html="icon.tip" @mouseenter="() => {
                    tip.style.opacity = 1
                }" @mouseleave="() => {
                    tip.style.opacity = 0
                }"></span>
                <span class="tip" ref="tip">{{ prop.conf.desc }}</span>
            </span>
        </div>
        <!-- 最外层用于触发 -->
        <div v-if="prop.conf.type == 'slider'" class="slider-bar" @mousedown="startDrag">
            <!-- 未走进度 -->
            <div class="background" ref="background">
                <!-- 已走进度 -->
                <div class="front" ref="front" :style="`width: ${getProgress(val) * 100}%;`"></div>
                <!-- 拖拽手柄 -->
                <div class="handle" ref="handle"></div>
            </div>
        </div>

        <input v-if="prop.conf.type == 'slider'" type="number" class="valInput" :value="val" @change="e => {
            setProgress(getProgress(e.target.value))
        }" :max="prop.conf.val.max" :min="prop.conf.val.min" :step="prop.conf.val.step ?? 0.01">


        <div v-if="prop.conf.type == 'toggle'" :class="'toggle ' + (prop.conf.val ? 'open' : '')" @click="() => {
            // 切换
            prop.conf.val = !prop.conf.val
            prop.conf.valChange(prop.conf.val)
        }">
            <div class="background">
                <div class="front"></div>
                <div class="front"></div>
            </div>
        </div>
    </div>
</template>

<script setup>
import { ref, onMounted, watch } from 'vue'
import { icon } from '@/assets/icons.js'

const prop = defineProps({
    conf: {
        type: Object
    }
})

// 传回的值
const val = ref(prop.conf.val.norm)

const handle = ref(null)
const background = ref(null)
const front = ref(null)
const tip = ref(null)


onMounted(() => {
    // 初始化

    // 将值转为百分比

    switch (prop.conf.type) {
        case 'slider':
            const temp = (val.value - prop.conf.val.min) / (prop.conf.val.max - prop.conf.val.min)
            setProgress(temp)
            break;

        default:
            break;
    }
})

watch(val, prop.conf.valChange)

function getProgress(value) {
    return (value - prop.conf.val.min) / (prop.conf.val.max - prop.conf.val.min)
}

function getVal(progress) {
    const step = prop.conf.val.step ?? 0.01

    // 计算小数数位

    const decimalPlaces = (step.toString().split('.')[1] || '').length
    const temp = 10 ** decimalPlaces

    // return (Math.round(progress * ((prop.conf.val.max - prop.conf.val.min) + prop.conf.val.min) / step * temp) * step / temp).toFixed(decimalPlaces)


    const ret = progress * (prop.conf.val.max - prop.conf.val.min) + prop.conf.val.min
    return Number((Math.round(ret / step * temp) * step / temp).toFixed(decimalPlaces))
}

function setProgress(progress) {
    // $(front.value).css({
    //     width: progress * 100 + '%'
    // })

    val.value = getVal(progress)
}

const moveHandle = e => {
    const left = e.pageX - background.value.offsetLeft
    let progress = left / background.value.clientWidth

    // 限制大小
    progress = progress <= 0 ? 0 : progress >= 1 ? 1 : progress

    // 转为实际数值
    setProgress(progress)
}

const startDrag = e => {
    moveHandle(e)

    document.documentElement.addEventListener('mouseup', () => {
        // isDragging.value = false
        document.documentElement.removeEventListener('mousemove', moveHandle)
    })
    document.documentElement.addEventListener('mousemove', moveHandle)
}

</script>

<style scoped lang="less">
@slider-bar-high: .2rem;
@slider-handle-size: .6rem;
@option-font-size: .9rem;

* {
    transition: all .3s;
}

.block {
    width: 100%;
    display: flex;
    justify-content: space-between;
    align-items: center;

    .desc-bar {
        display: flex;
        align-items: center;

        width: 32%;

        font-size: @option-font-size;

        .desc {
            position: relative;
            height: @option-font-size;
            text-indent: .1rem;

            .tip {
                position: absolute;
                top: 50%;
                padding: .1rem .3rem;
                white-space: nowrap;
                background: #ffffff99;
                border-radius: .3rem;

                backdrop-filter: blur(.2rem);

                box-shadow: .08rem .08rem .1rem #999;

                user-select: none;
                opacity: 0;
                transition: all .2s;

                pointer-events: none;

                z-index: 1;
            }

            /deep/ svg {
                width: @option-font-size;
            }
        }
    }

    .slider-bar {
        display: flex;
        align-items: center;
        width: 56%;
        padding: 0 3%;
        height: @option-font-size;

        user-select: none;

        &:hover {
            background: #00000011;
        }

        .background {
            display: flex;
            align-items: center;
            height: @slider-bar-high;
            width: 100%;

            background: #ccc;
            border-radius: 24px;

            .front {
                background: #3f84ca;
                height: @slider-bar-high;
                width: 0;
                transition: all .2s;
            }

            .handle {
                position: relative;
                right: 0;
                height: @slider-handle-size;
                width: @slider-handle-size;
                /* margin-top: calc((@slider-bar-high - @slider-handle-size) / 2); */

                margin-left: calc(@slider-handle-size / -2);
                background: #000;

                transition: all .2s;
            }
        }
    }

    .valInput {
        width: 12%;
    }

    .toggle {
        flex: auto;

        .background {
            position: relative;
            height: @option-font-size;
            width: @option-font-size * 3.2;
            background: #bbe0f6;
            filter: grayscale(1);

            .front {
                position: absolute;
                right: calc(100% - @option-font-size);
                height: 100%;
                width: @option-font-size;
                background: #3f84ca;

                &:last-child {
                    right: calc(70% - @option-font-size);
                    opacity: 0;
                }
            }
        }

        &.open {
            .background {

                filter: grayscale(0);

                .front {
                    right: 30%;
                    opacity: 0;


                    &:last-child {
                        right: 0;
                        opacity: 1;
                    }
                }
            }

        }
    }
}
</style>